import React from 'react';
import styles from './index.less';
import {Col, Row} from 'antd';
import {Modal, ActionSheet, Toast} from 'antd-mobile';
import {chatHistoryImg, chatImg, skinImg, swapImg} from '@/utils/images-res';
import {secondsToMinuteStr} from '@/utils/board-utils';
import {btnSound, messageSound, playSound} from '@/utils/sounds-res';
import {log} from '@/utils/log-utils';
import SocketEvent from '@/service/event';
import AdvancedBtn from "@/button";
import {resMap} from "@/utils/map-res";

/**
 * 用户信息展示
 */
class User extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      // 聊天窗口是否展示
      msgWindowShow: false,
      // 消息记录
      chatHistory: [],
      // 观战消息展示记录(仅临时缓存和展示)
      watchChatCache: [],
      watchChatObj: null,
      watchChatShow: false,
    }

    this.chat = '聊天';
    this.chatHistory = '消息记录'
    this.skin = '换肤';

    // 消息滚动条组件
    this.listRef = null;

    this.chatRespId = 'watchChatRespId';

    this.unRegisterServices = [];
    this.unRegisterServices.push(this.chatRespId);
  }

  componentDidMount() {
    this.watchChatIntervalId = setInterval(() => {
      const {watchChatCache, watchChatShow} = this.state;
      if (!watchChatShow && watchChatCache.length > 0) {
        const chatCacheLen = watchChatCache.length;
        const watchChatObj = watchChatCache[chatCacheLen - 1];
        watchChatCache.splice(0, chatCacheLen);
        this.setState({watchChatObj, watchChatShow: true, watchChatCache});
      }
    }, 120);

    // 聊天信息监听
    SocketEvent.register('chatRespApi', this.chatRespId, resp => {
      log('聊天消息，返回：', resp);
      if (resp.code === 'success') {
        const {chatHistory, watchChatCache} = this.state;
        const {userId, userName, content} = resp.data;
        const msgObj = {
          userId: userId,
          userName: userName,
          content: content,
        }
        // 聊天历史记录
        chatHistory.push(msgObj);
        // 消息显示记录
        watchChatCache.push(msgObj);
        this.setState({chatHistory, watchChatCache, watchChatShow: false});
        this.msgWindowToBottom();
        playSound(messageSound);
      } else {
        Toast.show(resp.msg);
      }
    });
  }

  componentWillUnmount() {
    clearInterval(this.watchChatIntervalId);
    SocketEvent.unRegister(this.unRegisterServices);
  }

  /**
   * 退出观战
   */
  exitWatch = e => {
    playSound(btnSound);
    const gameOver = this.props.gameOver;
    // 游戏结束直接退出
    if (gameOver) {
      SocketEvent.emit(this.props.socket, 'leaveWatchRoomApi', {
        userId: this.props.userId,
        roomId: this.props.roomId,
      }, resp => {
        log('离开房间返回：', resp);
        this.props.goBack();
      });
    } else {
      // 未结束弹出警示窗口
      Modal.alert('系统提示', '确认退出观战吗?', [
        {text: '取消', onPress: () => playSound(btnSound)},
        {
          text: '确认', onPress: () => {
            playSound(btnSound);
            SocketEvent.emit(this.props.socket, 'leaveWatchRoomApi', {
              userId: this.props.userId,
              roomId: this.props.roomId,
            }, resp => {
              log('离开房间返回：', resp);
              this.props.goBack();
            });
          },
        },
      ]);
    }
  };

  /**
   * 关闭聊天消息框
   * @param e
   */
  closeMsgWidow = e => {
    playSound(btnSound);
    this.setState({msgWindowShow: false});
    delete this.chatWindowIntervalId;
  };

  /**
   * 聊天
   */
  userChat = () => {
    playSound(btnSound);
    if (this.props.gameOver) {
      Toast.show('对战已经结束');
    } else {
      const {userDetail} = this.props;

      Modal.prompt('请输入聊天内容', '', [
        {text: '取消', onPress: () => playSound(btnSound)},
        {
          text: '发送', onPress: value => {
            playSound(btnSound);
            if (value.length === 0) {
              Toast.show('请输入有效的聊天内容');
            } else {
              const {chatHistory, watchChatCache} = this.state;
              const msgObj = {
                userId: this.props.userId,
                userName: userDetail.userName,
                content: value,
              };

              chatHistory.push(msgObj);
              watchChatCache.push(msgObj);

              SocketEvent.emit(this.props.socket, 'chatApi', {
                userId: this.props.userId,
                roomId: this.props.roomId,
                content: value,
              }, resp => {
                log('发送聊天消息返回：', resp);
                if (resp.code !== 'success') {
                  Toast.show(resp.msg);
                }
              });
              this.setState({
                chatHistory,
                watchChatCache,
                // 默认不关闭聊天窗口
                // msgWindowShow: false,
                // 有新消息进来，watchChatShow不显示，交由下一次显示最新消息
                watchChatShow: false
              });
              delete this.chatWindowIntervalId;
              // 消息拖到底部
              this.msgWindowToBottom();
            }
          },
        },
      ]);
    }
  };


  /**
   * 消息窗口是否展示
   */
  msgWindowView = () => {
    const {chatHistory} = this.state;
    const {userId, playOne, playTwo} = this.props;
    return (
      <div className={styles.msgWindow}>
        <div className={styles.title}>
          <div title={'icon'}/>
          <span>消息记录</span>
        </div>

        <div className={styles.content}>
          <div className={styles.list} ref={ref => this.listRef = ref}>
            {
              chatHistory.map((item, index) => {
                // 不同用户，显示不同的颜色
                let clsName = styles.default;
                if (item.userId === userId) {
                  // 自己-观战方
                  clsName = styles.tourist;
                } else if (item.userId === playOne.userId) {
                  // 房间用户A
                  clsName = styles.self;
                } else if (item.userId === playTwo.userId) {
                  // 房间用户B
                  clsName = styles.enemys;
                }
                return (
                  <p key={`msg_${index}`}>
                    <span className={clsName}>{item.userName}：{item.content}</span>
                  </p>
                );
              })
            }
          </div>
          <div className={styles.floor}>
            <Row>
              <Col span={7}>
                <AdvancedBtn type="normal" text='常用语'/>
              </Col>
              <Col span={1}/>
              <Col span={7}>
                <AdvancedBtn type="normal" text='编辑' onClick={e => this.userChat(e)}/>
              </Col>
              <Col span={1}/>
              <Col span={8}>
                <AdvancedBtn type="danger" text='关闭' onClick={e => this.closeMsgWidow(e)}/>
              </Col>
            </Row>
          </div>
        </div>
      </div>
    );
  };

  /**
   * 将聊天消息拖到最底部
   */
  msgWindowToBottom = () => {
    // 防止创建多个interval
    if (!this.chatWindowIntervalId) {
      const maxTryCount = 100;
      let tryCount = 0;
      this.chatWindowIntervalId = setInterval(() => {
        if (this.listRef || ++tryCount >= maxTryCount) {
          if(this.listRef) {
            this.listRef.scrollTop = this.listRef.scrollHeight;
          }
          clearInterval(this.chatWindowIntervalId);
          delete this.chatWindowIntervalId;
          log('将聊天消息拖到最底部，已完成');
        }
      }, 1);
    }
  };

  /**
   * 显示菜单
   */
  showMenuList = () => {
    playSound(btnSound);
    if (this.props.gameOver) {
      Toast.show('对局已结束');
      return;
    }

    const lineDataList = [];
    lineDataList.push({icon: <img src={chatImg} alt='' style={{width: 36}}/>, title: this.chat});
    lineDataList.push({icon: <img src={chatHistoryImg} alt='' style={{width: 36}}/>, title: this.chatHistory});
    lineDataList.push({icon: <img src={skinImg} alt='' style={{width: 36}}/>, title: this.skin});

    ActionSheet.showShareActionSheetWithOptions({
        options: lineDataList,
        message: '菜单',
      },
      (buttonIndex, rowIndex) => {
        const itemName = buttonIndex > -1 ? lineDataList[buttonIndex].title : 'cancel';
        playSound(btnSound);
        if (itemName === this.skin) {
          Toast.show('皮肤功能未开放')
        } else if (itemName === this.chat) {
          // 直接打开聊天窗口
          this.userChat();
        } else if (itemName === this.chatHistory) {
          // 打开历史记录窗口
          this.setState({msgWindowShow: true});
          this.msgWindowToBottom();
        }
      });
  }

  render() {
    const {playOne, playTwo, isRedMove, gameOver, gameOverMsg} = this.props;
    const {watchChatShow, watchChatObj} = this.state;
    const watchMsg = `[${watchChatObj?.userName}]: ${watchChatObj?.content}`;
    const bBoss = resMap.get('black');
    const wBoss = resMap.get('white');
    return (
      <div>
        {/*弹窗提示*/}
        {gameOver && <div className={styles.over}>{gameOverMsg}</div>}

        {/*页面布局*/}
        <div className={styles.player}>
          <Row className={styles.user}>
            <Col span={4}>
              <div className={styles.icon} hidden={!playOne.userId}>
                <div className={playOne.first !== isRedMove ? styles.defBorder : styles.border}>
                  <img src={playOne.first ? bBoss : wBoss} width='100%' height='100%' alt={''}/>
                </div>
              </div>
            </Col>
            <Col span={15} className={styles.body}>
              <Row>
                <Col span={14} className={styles.name}>{playOne.userName}</Col>
                <Col span={10} className={styles.score}>{playOne.score}</Col>
              </Row>
              <Row>
                <Col span={12} hidden={!playOne.userId}
                     className={styles.allTime}>局时 <span>{secondsToMinuteStr(playOne.allTime)}</span></Col>
                <Col span={12} hidden={!playOne.userId}
                     className={styles.stepTime}>步时 <span>{secondsToMinuteStr(playOne.stepTime)}</span></Col>
              </Row>
            </Col>
            <Col span={5}>
              <div className={styles.floor}>
                <AdvancedBtn type={'square'} text='退出' onClick={e => this.exitWatch(e)}/>
              </div>
            </Col>
          </Row>
          <Row className={styles.enemy}>
            <Col span={4}>
              <div className={styles.icon} hidden={!playTwo.userId}>
                <div className={playTwo.first !== isRedMove ? styles.defBorder : styles.border}>
                  <img src={playTwo.first ? bBoss : wBoss} width={'100%'} height={'100%'} alt={''}/>
                </div>
              </div>
            </Col>
            <Col span={15} className={styles.body}>
              <Row>
                <Col span={14} className={styles.name}>{playTwo.userName}</Col>
                <Col span={10} className={styles.score}>{playTwo.score}</Col>
              </Row>
              <Row>
                <Col span={12} hidden={!playTwo.userId}
                     className={styles.allTime}>局时 <span>{secondsToMinuteStr(playTwo.allTime)}</span></Col>
                <Col span={12} hidden={!playTwo.userId}
                     className={styles.stepTime}>步时 <span>{secondsToMinuteStr(playTwo.stepTime)}</span></Col>
              </Row>
            </Col>
            <Col span={5}>
              <div className={styles.floor}>
                <AdvancedBtn type={'square'} text='菜单' onClick={this.showMenuList}/>
              </div>
            </Col>
          </Row>
        </div>

        <div className={styles.watchMsg}>
          {
            watchChatShow && <div
              onAnimationStart={e => this.setState({watchChatShow: watchMsg.length > 5})}
              onAnimationEnd={e => this.setState({watchChatShow: false})}>
              {watchMsg}
            </div>
          }
        </div>

        {/*发送聊天消息弹窗组件*/}
        {(this.state.msgWindowShow && !this.props.gameOver) ? this.msgWindowView() : ''}
      </div>
    );
  }
}

export default User;
